#pragma once

#include "TextBox.h"
#include "Drawable.h"
#include "DirectInput.h"
#include "Vector.hpp"
#include <Windows.h>
#include <sstream>

// struct for camera vectors
struct d3dCamera
{
	D3DXVECTOR3 eyePos;
	D3DXVECTOR3 lookAt;
	D3DXVECTOR3	upVec;
};

const int g_numPieces = 42;
const int g_numTextures = 4;

// singleton graphics engine
class Graphics
{
private:
	Graphics();							// private ctor allows this class to be a singleton

	// member variables
	IDirect3DDevice9*			m_pD3DDevice;						// the main device of the Graphics class
	ID3DXSprite*				m_pD3DSprite;						// sprite handler
	LPDIRECT3DTEXTURE9			m_pButtonTexture;
	HWND						m_hWnd;								// a copy of hWnd from main.cpp
	Dimensions					m_dimScreen;						// a copy of the screen dimensions
	bool						m_bWindowed;						// false means the window is fullscreen
	D3DPRESENT_PARAMETERS		m_D3Dpp;							// present parameters
	bool						m_bInitialized;
	D3DLIGHT9					m_DefaultLight;
	D3DLIGHT9					m_DefaultLight2;

	d3dCamera					m_Camera;							// holds the camera related vectors

	char*						m_cszCubeMeshFile;
	char*						m_cszBoardMeshFile;
	ID3DXMesh*					m_pCubeMesh;
	ID3DXMesh*					m_pBoardMesh;

	Vector<Vec3D>				m_PieceList[g_numPieces];			// an array with each piece's set of coordinates
	char*						m_cszTextureFileName[g_numTextures];
	LPDIRECT3DTEXTURE9			m_pTextureLibrary[g_numTextures];	// array that stores all the textures
	D3DMATERIAL9				m_DefaultMaterial;					// the default material that all players will use
	D3DMATERIAL9				m_SelectionMaterial;				// the material a selected piece will use

	ID3DXFont*					m_pD3DFont;							// the font handler
	RECT						m_rTextBox;
	std::stringstream			m_FontStream;

	// matrices used for camera
	D3DXMATRIX					m_matPerspective;
	D3DXMATRIX					m_matView;

	// matrices used for world matrix computations
	D3DXMATRIX					m_matWorld;

	// subfunctions of Init()
	bool SetupDevice(HWND hWnd);
	bool SetupCamera();
	bool SetupFont();
	bool SetupMeshes();
	bool SetupLight();
	bool SetupMaterials();
	void RenderFont(TextBox* toRender);
	void MoveCameraTo(D3DXVECTOR3 newPos);

public:
	bool Init(HWND hWnd);
	static inline Graphics* Engine()	// function used to access the singleton
	{ static Graphics g; return &g; }

	void setPiece(bool** shape, int index, int size);
	void LoadMeshFile(const char* cszXFile, ID3DXMesh*& pMesh);
	bool Render(Vector<Drawable*> vDrawables, Vector<TextBox*> vTextBoxes);

	~Graphics();
};

